package com.fudan.es.entity;

import java.util.ArrayList;
import java.util.List;

import org.elasticsearch.search.aggregations.AggregationBuilder;

import com.fudan.es.Aggs;
import com.fudan.es.aggs.DimensionParser.DimensionType;
import com.fudan.es.aggs.entity.DimensionDef;
import com.fudan.es.aggs.handler.base.AggsHandler;
import com.fudan.es.aggs.request.handler.dimension.DimensionHandler;

public class DimensionPack extends Pack{
	private DimensionDef dimension;
	private String name;
	private DimensionType type;
	private FieldMeta field;
	private Integer size = 10;
	private String interval = "1M";

	private String missing;
	private String other;

	private List<MetricPack> metric = new ArrayList<>();

	public static DimensionPack build(FieldMeta field,DimensionType type,DimensionDef dimension) {
		DimensionPack pack = new DimensionPack();
		pack.field = field;
		pack.type = type;
		pack.dimension = dimension;
		pack.interval = dimension.getInterval();
		//DimensionHandler handler = DimensionHandler.buildHandler(type);
		//pack.root = handler.handle(pack);
		AggsHandler dimensionHandler = AggsHandler.buildHandler(type);
		pack.root = dimensionHandler.handle(pack);
		return pack;
	}

	public static DimensionPack buildDefault() {
		DimensionPack pack = new DimensionPack();
		FieldMeta field = new FieldMeta();
		field.setInNested(false);
		pack.setField(field);
		pack.root = Aggs.matchAllFilter();
		return pack;
	}


	public DimensionPack addMetric(MetricPack metric) {
		FieldMeta metricField = metric.getField();
		if(metricField.getInNested()) {
			if(field.getInNested()) {
				if(field.getNestedPath().equals(metricField.getNestedPath())) {
					root.subAggregation(metric.getRoot());
				}else if(field.getNestedPath().contains(metricField.getNestedPath())) {
					//root->sub (reverse:sub_path)
					AggregationBuilder aggs = getreverseByPath(metricField.getNestedPath()).subAggregation(metric.getRoot());
				}else if(metricField.getNestedPath().contains(field.getNestedPath())) {
					//sub->root (nested:sub_path)
					AggregationBuilder aggs = getNestedByPath(metricField.getNestedPath()).subAggregation(metric.getRoot());
				}else {
					//root->reverse->nested(reverse:root->nested:sub_path)
					AggregationBuilder aggs = getreverseByPath(null).subAggregation(Aggs.nested(metricField.getNestedPath(), metricField.getNestedPath()).subAggregation(metric.getRoot()));
				}
			}
			else {
				//root:no,sub:nested
				AggregationBuilder aggs = getNestedByPath(metricField.getNestedPath()).subAggregation(metric.getRoot());
			}
		}else {
			if(field.getInNested()) {
				//root:nested,sub:no
				AggregationBuilder aggs = getreverseByPath(null).subAggregation(metric.getRoot());
			}else {
				//root:no,sub:no
				root.subAggregation(metric.getRoot());
			}
		}
		this.metric.add(metric);
		return this;
	}

	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public DimensionType getType() {
		return type;
	}
	public void setType(DimensionType type) {
		this.type = type;
	}
	public Integer getSize() {
		return size;
	}
	public void setSize(Integer size) {
		this.size = size;
	}
	public String getInterval() {
		return interval;
	}
	public void setInterval(String interval) {
		this.interval = interval;
	}

	public FieldMeta getField() {
		return field;
	}

	public void setField(FieldMeta field) {
		this.field = field;
	}

	public AggregationBuilder getRoot() {
		return root;
	}

	public void setRoot(AggregationBuilder root) {
		this.root = root;
	}

	public List<MetricPack> getMetric() {
		return metric;
	}

	public void setMetric(List<MetricPack> metric) {
		this.metric = metric;
	}

	public String getMissing() {
		return missing;
	}

	public void setMissing(String missing) {
		this.missing = missing;
	}

	public String getOther() {
		return other;
	}

	public void setOther(String other) {
		this.other = other;
	}

	public DimensionDef getDimension() {
		return dimension;
	}

	public void setDimension(DimensionDef dimension) {
		this.dimension = dimension;
	}

}
